﻿using System;
using System.Diagnostics;
using System.Linq;
using CodeFirst.Data;

namespace CodeFirst.Test
{
    static class TestNavigation
    {
        private static void AddNewChildEntity_InsertCollection(int blogid)
        {
            using (var db = new BlogContext())
            {
                var blog = db.Blogs.Find(blogid);
                var newPost = new Post { Content = "new post", DateCreated = DateTime.Now };
                var newComment = new Comment { Content = "new comment", DateCreated = DateTime.Now };

                newPost.AddComment(newComment);
                blog.AddPost(newPost);

                int affected = db.SaveChanges();
                Console.WriteLine("{0} rows affected", affected);
            }
        }

        /// <summary>
        /// because we don't declare "virtual" before "Blog.Posts" property
        /// so "lazy loading" is turned off
        /// </summary>
        /// <param name="blogid"></param>
        private static void TestLazyLoading_TurnedOff(int blogid)
        {
            using (var db = new BlogContext())
            {
                var blog = db.Blogs.Find(blogid);

                if (blog.Posts == null)
                {
                    Console.WriteLine("!!! No Posts are loaded with blog#{0}", blogid);
                }
                else
                {
                    int count = blog.Posts.Count;
                    Console.WriteLine("{0} posts loaded with blog#{1}", count, blogid);
                }
            }//using
        }

        private static void TestExplictLoading(int blogid)
        {
            using (var db = new BlogContext())
            {
                var blog = db.Blogs.Find(blogid);
                Debug.Assert(blog.Posts == null);

                db.Entry(blog).Collection(b => b.Posts).Load();

                int counter = 0;
                foreach (var post in blog.Posts)
                {
                    ++counter;
                    Console.WriteLine("[{0}] Post#{1} BlogId={2}", counter, post.Id, post.BlogId);
                }
            }
        }

        private static void AddComments(int blogid, int number)
        {
            using (var db = new BlogContext())
            {
                var posts = db.Posts.Where(p => p.BlogId == blogid);

                foreach (var post in posts)
                {
                    for (int index = 0; index < number; index++)
                    {
                        var comment = new Comment
                                          {
                                              Post = post,
                                              Content = string.Format("comment-{0}-{1}", post.Id, index),
                                              DateCreated = DateTime.Now
                                          };
                        db.Comments.Add(comment);
                    }
                }

                int affected = db.SaveChanges();
                Console.WriteLine("{0} rows affected", affected);
            }
        }

        private static void TestJoinSelect(int blogid)
        {
            using (var db = new BlogContext())
            {
                var query = from post in db.Posts
                            where post.BlogId == blogid
                            join comment in db.Comments on post.Id equals comment.PostId
                                into commentGroup
                            select new
                                       {
                                           PostId = post.Id,
                                           NumComments = commentGroup.Count()
                                       };

                foreach (var tuple in query)
                {
                    Console.WriteLine("Post#{0} has [{1}] comments", tuple.PostId, tuple.NumComments);
                }
            }
        }

        public static void TestMain()
        {
            int blogid = 3;
            // AddNewChildEntity_InsertCollection(blogid);
            // TestLazyLoading_TurnedOff(blogid);
            // TestExplictLoading(blogid);
            AddComments(blogid, 4);
            TestJoinSelect(blogid);
        }
    }
}
